#!/usr/bin/env python
# -*- coding: utf-8 -*-

from tornado import gen
import tornado.tcpserver
from tornado.ioloop import IOLoop

import time

from extend import Master, Worker, set_timeout
from dm_py_util import DEBUG_LOG, ERROR_LOG, INFO_LOG

class Connection(object):
    def __init__(self, stream, address, server, authorize_timeout=1000):
        self.stream = stream
        self.address = address
        self.stream.set_close_callback(self.__on_close)
        self._ahthorize_timeout = None
        self._authorized = False
        self.server = server

    def start_serving(self):
        pass

    def __on_close(self):
        self.on_close()
        self.server.connection_close(self)

    def on_close(self):
        DEBUG_LOG('connection lost', self.address)

class TCPHandler(tornado.tcpserver.TCPServer):
    conn_class = Connection
    def __init__(self, io_loop=None, ssl_options=None, max_buffer_size=None,
            read_chunk_size=None, **kwargs):
        super(TCPHandler, self).__init__(io_loop=io_loop, ssl_options=ssl_options, 
                max_buffer_size=max_buffer_size, read_chunk_size=read_chunk_size)
        self.conn_class = kwargs.get('connection', Connection)
        self._connections = set()

    def on_connection_made(self, conn):
        pass

    def __on_connection_made(self, conn):
        self._connections.add(conn)
        self.on_connection_made(conn)

    def handle_stream(self, stream, address):
        conn = self.conn_class(stream, address, self)
        self.__on_connection_made(conn)
        conn.start_serving()
        INFO_LOG('new connection', stream, address)

    def connection_close(self, conn):
        self._connections.remove(conn)
        INFO_LOG('connection lost')

    @property
    def connections(self):
        return self._connections

class TCPWorker(Worker):
    def init(self, config):
        DEBUG_LOG('worker init', config)

    def start(self):
        pass

class Server(Master):
    def __init__(self, worker=TCPWorker, main_config='', handler=TCPHandler, **kwargs):
        super(Server, self).__init__(worker=worker, main_config=main_config)
        self.handler = handler
        self.kwargs = kwargs

    def run(self):
        self.__init_master__(self.config)
        self.serve_forever()

    def __init_master__(self, config):
        self.init_master(config)

    def init_master(self, config):
        DEBUG_LOG('init master')

    def init_server(self):
        server = self.handler(**self.kwargs)
        return server



if __name__ == '__main__':
    s = Server(main_config='./conf/tcp.ini')
    s.run()
